home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1990
/
05
/
wserver.asm
< prev
next >
Wrap
Assembly Source File
|
1990-08-03
|
14KB
|
474 lines
title window server
include window.inc
include asm.inc
; (c) 1990 Soft Advances, all rights reserved.
; server window structure
;
window_str struc
w_origin_x db ?
w_origin_y db ?
w_corner_x db ?
w_corner_y db ?
w_parent dw ?
w_sibling dw ?
w_child dw ?
window_str ends
;
w_origin equ word ptr w_origin_x
w_corner equ word ptr w_corner_x
; local variables for WDrawText and clipping procedures
;
ct_locals struc
ct_offset dw ? ; text pointer offset
ct_segment dw ? ; segment
ct_windowId dw ? ; active window handle
ct_attribute dw ?
ct_locals ends
.data?
w_pointers dd WINDOW_MAX dup(?)
w_count dw ? ; number of open windows
root_child dw ? ; first child for root window
WRep_s _WRep <>
WReq_s _WReq <>
.code
extn save_most,calloc_read,receive_window_request,transmit_window_reply
extn write_video_memory
public poll_server
;; alloc window struct
;
; exit AX windowId
; DS:SI window structure
; Cf if no memory or too many windows
;
alloc_window_struct proc
mov ax,w_count[bp] ; check window count
cmp ax,WINDOW_MAX
jae aws2 ; if too many windows
inc ax ; update window count
pushm ax,cx,di
mov di,ax
mov w_count[bp],ax
mov cx,size window_str ; allocate window structure
call calloc_read
jc aws1 ; if no memory
add di,di ; put structure address in table
add di,di
mov wptr w_pointers[bp+di],si
mov wptr w_pointers[bp+di+2],ds
aws1: popm di,cx,ax
ret
aws2: stc
ret
alloc_window_struct endp
;; clip aunt text
;
; entry BX windowId (most distant grandparent)
; CX byte count
; DL column
; DH row
; DS:SI window structure for BX
; BP+DI local variables
; uses AX,BX,CX,DX,SI,DS,DI
;
clip_aunt_text proc
cat1: mov bx,w_sibling[si] ; process overlapping siblings of most
cmp bx,NULL_SIBLING ; distant grandparent
je cat4 ; (if no more siblings)
call read_window_struct
cmp dh,w_origin_y[si] ; check for overlapping window
jb cat1 ; if no overlap
cmp dh,w_corner_y[si]
jae cat1 ; if no overlap
cmp dl,w_corner_x[si]
jae cat1 ; if no overlap
mov ax,cx
add al,dl
cmp al,w_origin_x[si]
jb cat1 ; if no overlap
cmp dl,w_origin_x[si]
jae cat3 ; if left overlap
cmp al,w_corner_x[si]
jbe cat2 ; if right overlap
pushm ax,bx,cx,dx,di,si,ds ; else middle overlap
push ct_offset[bp+di] ; save current state and process
call cat3 ; exposed right side line fragment,
popm ct_offset[bp+di] ; then restore and process exposed
popm ds,si,di,dx,cx,bx,ax ; left side line fragment
cat2: sub al,w_origin_x[si] ; here for right overlap
sub cx,ax
jmp cat1
cat3: mov al,w_corner_x[si] ; here for left overlap
sub al,dl
jbe cat5 ; if complete overlap
add dl,al ; set new X coordinate (DL=corner_x)
sub cx,ax ; adjust byte count and text offset
add ct_offset[bp+di],ax
jmp cat1
cat4: mov ax,ct_attribute[bp+di] ; write text to display memory
lds si,dptr ct_offset[bp+di]
jmp write_video_memory
cat5: ret
clip_aunt_text endp
;; clip parent text
;
; entry CX byte count
; DL column
; DH row
; BP+DI local variables
; uses AX,BX,CX,DX,SI,DS,DI
;
clip_parent_text proc
mov bx,ct_windowId[bp+di]
call read_window_struct
cpt1: mov ax,w_parent[si]
cmp ax,NULL_PARENT
je clip_aunt_text ; if no more ancestors
mov bx,ax
call read_window_struct
add dl,w_origin_x[si]
jc cpt2 ; if outside window limits
add dh,w_origin_y[si]
jc cpt2 ; if outside window limits
cmp dh,w_corner_y[si]
jae cpt2 ; if below parent window
mov al,w_corner_x[si]
cmp dl,al
jae cpt2 ; if right of parent window
sub al,dl
mov ah,0
cmp ax,cx
jae cpt1 ; if line fits in parent window
mov cx,ax ; else clip end of line
jmp cpt1
cpt2: ret
clip_parent_text endp
;; clip sibling text
;
; entry CX byte count
; DL column
; DH row
; DS:SI active window structure
; BP+DI local variables
; uses AX,BX,CX,DX,SI,DS,DI
;
clip_sibling_text proc
cbt1: mov bx,w_sibling[si]
cmp bx,NULL_SIBLING
je clip_parent_text ; if no more siblings
call read_window_struct
cmp dh,w_origin_y[si] ; check for overlapping windows
jb cbt1 ; if no overlap
cmp dh,w_corner_y[si]
jae cbt1 ; if no overlap
cmp dl,w_corner_x[si]
jae cbt1 ; if no overlap
mov ax,cx
add al,dl
cmp al,w_origin_x[si]
jb cbt1 ; if no overlap
cmp dl,w_origin_x[si]
jae cbt3 ; if left overlap
cmp al,w_corner_x[si]
jbe cbt2 ; if right overlap
pushm ax,bx,cx,dx,di,si,ds ; else middle overlap
push ct_offset[bp+di] ; save current state and process
call cbt3 ; exposed right side line fragment,
popm ct_offset[bp+di] ; then restore and process exposed
popm ds,si,di,dx,cx,bx,ax ; left side line fragment
cbt2: sub al,w_origin_x[si] ; here for right overlap
sub cx,ax
jmp cbt1
cbt3: mov al,w_corner_x[si] ; here for left overlap
sub al,dl
jbe cbt4 ; if complete overlap
add dl,al ; set new X coordinate (DL=corner_x)
sub cx,ax ; adjust byte count and text offset
add ct_offset[bp+di],ax
jmp cbt1
cbt4: ret
clip_sibling_text endp
;; clip window text
;
; entry BX windowId (start with active window)
; CX byte count
; DL column
; DH row
; BP+DI local variables
; uses AX,BX,CX,DX,SI,DS,DI
;
clip_window_text proc
call read_window_struct
jc cwt1 ; if bad windowId
add dl,w_origin_x[si]
jc cwt1 ; if outside window limits
add dh,w_origin_y[si]
jc cwt1 ; if outside window limits
cmp dh,w_corner_y[si]
jae cwt1 ; if below window
mov al,w_corner_x[si]
cmp dl,al
jae cwt1 ; if right of window
sub al,dl
mov ah,0
cmp ax,cx
jae clip_sibling_text ; if line fits in parent window
mov cx,ax ; else clip end of line
jmp clip_sibling_text
cwt1: ret
clip_window_text endp
;; create window
;
; entry DS:SI request packet
; uses AX,BX,CX,DX,SI,DS
;
create_window proc
mov bx,WReq_windowId[si] ; (get parent window)
mov cx,WReq_y_x[si]
mov dx,WReq_height_width[si]
call create_window_primitive
jc cwd1 ; if no storage or bad coordinate
call reply_packet_read
mov WRep_code[si],W_Reply
mov WRep_windowId[si],ax
jmp transmit_window_reply
cwd1: call reply_packet_read
mov WRep_code[si],W_Error
mov WRep_error_code[si],ax
jmp transmit_window_reply ;\
create_window endp
;; create window primitive
;
; entry BX parent window
; CL left most column (parent relative)
; CH top most row (parent relative)
; DL width
; DH height
; exit AX windowId or error code
; Cf if no storage or bad coordinate
; uses SI,DS
;
create_window_primitive proc
add dh,ch ; window corner is lower right y+1 x+1
jc cwp1 ; if vertical overflow
add dl,cl
jc cwp1 ; if horizontal overflow
call alloc_window_struct
jc cwp2 ; if no storage
mov w_parent[si],bx
mov w_origin[si],cx
mov w_corner[si],dx
mov w_child[si],NULL_WINDOW
mov w_sibling[si],NULL_WINDOW
jmp link_new_sibling
cwp1: mov ax,BadValue
ret
cwp2: mov ax,BadAlloc
ret
create_window_primitive endp
;; destroy window
;
destroy_window proc
ret
destroy_window endp
;; link new sibling
;
; entry AX new windowId
; BX parent windowId
; uses SI,DS
;
link_new_sibling proc
push bx
cmp bx,NULL_WINDOW
je lns3 ; if child of root window
call read_window_struct ; else child of normal window
mov bx,w_child[si]
cmp bx,NULL_WINDOW
je lns2 ; if first child of this window
lns1: call read_window_struct ; else find youngest sibling
mov bx,w_sibling[si]
cmp bx,NULL_WINDOW
jne lns1
mov w_sibling[si],ax ; and link new sibling
jmp lns4
lns2: mov w_child[si],ax
jmp lns4
lns3: mov bx,root_child[bp] ; set first generation child
cmp bx,NULL_WINDOW
jne lns1 ; if not the first child of root
mov root_child[bp],ax
lns4: pop bx
ret
link_new_sibling endp
;; poll server
;
; uses AX
;
poll_server proc
call save_most
mov cx,SIZEOF_WREQ
push ss
pop ds
lea si,WReq_s[bp]
call receive_window_request
jc psv1 ; if no request pending
call process_server_request
psv1: ret
poll_server endp
;; process server request
;
; entry DS:SI request packet
; exit
; uses AX
;
process_server_request proc
mov al,WReq_code[si]
cmp al,W_CreateWindow
je psr1 ; if window open
cmp al,W_DestroyWindow
je psr2 ; if window close
cmp al,W_Text
je psr3 ; if text output
ret ; else ignore unknown requests
psr1: jmp create_window
psr2: jmp destroy_window
psr3: jmp window_text
process_server_request endp
;; read window struct
;
; entry BX windowId
; exit DS:SI window structure
; Cf if bad windowId
;
read_window_struct proc
push cx
cmp bx,WINDOW_MAX
jae rws2 ; if bad windowId
mov si,bx
add si,si
add si,si
lds si,w_pointers[bp+si]
mov cx,ds
jcxz rws2 ; if bad windowId
rws1: pop cx
ret
rws2: stc
jmp rws1
read_window_struct endp
;; reply packet read
;
; exit DS:SI reply packet pointer
; CX byte count
;
reply_packet_read proc
push ss
pop ds
lea si,WRep_s[bp]
mov cx,SIZEOF_WREP
ret
reply_packet_read endp
;; window text
;
; entry DS:SI window request packet
; uses AX,BX,CX,DX,DI,SI,DS,ES
;
window_text proc
sub sp,size ct_locals
mov di,sp
sub di,bp
mov ax,WReq_windowId[si] ; set local variables
mov ct_windowId[bp+di],ax
mov ax,WReq_attribute[si]
mov ct_attribute[bp+di],ax
mov cx,WReq_count[si] ; receive window text
lea si,WReq_text[si]
call receive_window_request
jc wdt1 ; if internal error
mov ct_offset[bp+di],si ; set text pointer
mov ct_segment[bp+di],ds
call clip_window_text ; clip text and write to video memory
wdt1: lea sp,[bp+di+size ct_locals]
ret
window_text endp
end